home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / pcl4c34.zip / TERM.C < prev    next >
Text File  |  1993-01-01  |  11KB  |  402 lines

  1. /*
  2. **                    ---  term.c ---
  3. **
  4. **  EXAMPLE CODE: Terminal emulator. Can transfer files using
  5. **  XMODEM, YMODEM, and YMODEM-G protocols.
  6. **
  7. **  See TERM.H for configuration parameters.
  8. **
  9. **  Link with TERM_IO, MODEM_IO, DIR_IO, CRC, DOS, XYMODEM, and XYPACKET.
  10. **  See TERM makefiles.
  11. **
  12. **  Do NOT select YMODEM-G when using a null modem cable unless you are
  13. **  certain that RTS & CTS are reversed ( this is usually not true ).
  14. **
  15. **  This example program (not the PCL4C library) is donated to
  16. **  the Public Domain by MarshallSoft Computing, Inc. It is
  17. **  provided as an example of the use of the PCL4C.
  18. **
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <fcntl.h>
  23. #include <sys\types.h>
  24. #include <sys\stat.h>
  25. #include "pcl4c.h"
  26. #include "ascii.h"
  27. #include "term.h"
  28. #include "dir_io.h"
  29.  
  30. #define FALSE 0
  31. #define TRUE !FALSE
  32. #define NORMAL 0x07
  33. #define INVERSE 0x70
  34. #define MESSAGE_POS 48
  35.  
  36. void MyCrtWrite();
  37. void MyStart();
  38. void ProcessESC();
  39. void ShowProtocol();
  40. void ShowMessage();
  41. void MyExit();
  42. void SayFilename();
  43. void ErrorCheck();
  44.  
  45. /*** Global variables ***/
  46.  
  47. int Port;               /* current COM port [0..3] */
  48. char FileSpec[15];      /* file name specification */
  49. char Filename[15];      /* file name buffer */
  50. char Buffer[1024];      /* block buffer */
  51. char RxBuf[2048];       /* receive buffer */
  52. char *BaudRate[10] =  {"300","600","1200","2400","4800","9600",
  53.                        "19200","38400","57600","115200"};
  54. int BaudCode;           /* baud rate code ( index into BaudRate[] ) */
  55. char *ModelText[4] = {"Small","Compact","Medium","Large"};
  56. char NCGchar  = NAK;
  57. int OneKflag  = FALSE;
  58. int BatchFlag = FALSE;
  59. char Protocol = 'X';
  60.  
  61. /*** main program ***/
  62.  
  63. main(argc,argv)
  64. int argc;
  65. char *argv[];
  66. {int DataFlag = FALSE;
  67.  char c;
  68.  int i, k;
  69.  int n, rc;
  70.  int Delta;         /* delta port status */
  71.  int Status;        /* port status */
  72.  char Version;
  73.  char temp[81];
  74.  /* right number of parameters ? */
  75.  if(argc!=3)
  76.      {printf("Usage: 'TERM port baud' -- example 'TERM 1 9600'\n");
  77.       exit(1);
  78.      }
  79.  /* get port number from command line */
  80.  Port = atoi(argv[1]) - 1;
  81.  if((Port<0) || (Port>3))
  82.      {printf("Port must be 1 to 4\n");
  83.       exit(1);
  84.      }
  85.  /* get baud rate from command line */
  86.  BaudCode = BaudMatch(argv[2]);
  87.  if(BaudCode<0)
  88.      {printf("Cannot recognize baud rate = %s\n",argv[2]);
  89.       exit(1);
  90.      }
  91.  /*** Custom Configuration ***/
  92. #if 0
  93.  /* use IRQ2 for COM3 */
  94.  SioIRQ(COM3,IRQ2,ThirdISR);
  95.  /* use IRQ5 for COM4 */
  96.  SioIRQ(COM4,IRQ5,FourthISR);
  97. #endif
  98.  /* setup receive buffer */
  99.  ErrorCheck( SioRxBuf(Port,RxBuf,Size2K) );
  100.  /* set parms & reset (initialize) COM port */
  101.  ErrorCheck( SioParms(Port,NoParity,OneStopBit,WordLength8) );
  102.  MyStart(Port,BaudCode);
  103.  /* set DTR and RTS */
  104.  SioDTR(Port,'S');
  105.  SioRTS(Port,'S');
  106.  /* init CRC table */
  107.  InitCRC();
  108.  /* initialize screen */
  109.  Scroll(0,0,24,79,0,NORMAL);
  110.  /* display status message */
  111.  sprintf(temp," COM%d %s %c 'ESC for menu'  ",1+Port,BaudRate[BaudCode],Protocol);
  112.  ShowMessage(0,temp);
  113.  Position(1,0);
  114.  /* display some info */
  115.  puts("TERM 10/30/92");
  116.  Version = SioInfo('V');
  117.  printf("Library = %d.%d\n",Version/16,Version%16);
  118.  printf("Memory Model = %s\n",ModelText[3&SioInfo('M')] );
  119. #if RTS_CTS_CONTROL
  120.  SioFlow(Port,7*ONE_SECOND);
  121.  printf("Flow Control enabled. CTS = ");
  122.  if(SioCTS(Port)) puts("ON");
  123.  else puts("OFF");
  124. #endif
  125.  /* Set FIFO level */
  126.  if( SioFIFO(Port,LEVEL_14) ) puts("INS16550 detected");
  127.  /* clear PCL4C receive buffer */
  128.  ErrorCheck( SioRxFlush(Port) );
  129.  
  130.  /* see TERM.H for definition of AT_COMMAND_SET */
  131. #if AT_COMMAND_SET
  132.  /* wait for Modem to say its ready */
  133.  printf("Waiting for Modem DSR.");
  134.  while( !SioDSR(Port) )
  135.      {
  136.       if(SioKeyPress()||SioBrkKey()) MyExit(0,"Aborted by user");
  137.       putchar('.');
  138.       SioDelay(18);
  139.      }
  140.  putchar('\n');
  141.  /* initialize (Hayes compatible) modem */
  142.  SendTo(Port,"!AT!!~");
  143.  SendTo(Port,"!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!");
  144.  if(WaitFor(Port,"OK")) printf("\nMODEM READY\n");
  145.  else printf("\nWARNING: Expected OK not received\n");
  146. #endif
  147.  
  148.  /* enter terminal loop */
  149.  SioRxFlush(Port);
  150.  while(1)
  151.      {/* Control-BREAK ? */
  152.       if(SioBrkKey()) MyExit(0,"User pressed Ctrl-BREAK");
  153.       /* was key pressed ? */
  154.       if(SioKeyPress())
  155.           {/* read key press */
  156.            i = SioKeyRead();
  157.            if((char)i==ESC)
  158.                {/* process user's request */
  159.                 ProcessESC();
  160.                 ShowMessage(strlen(BaudRate[BaudCode])+9,"'ESC for Menu' ");
  161.                 continue;
  162.                }
  163.            else PutChar(Port,i);
  164.           }
  165.       /* was break detected ? */
  166.       if( SioBrkSig(Port,'D') ) DisplayLine("BREAK detected ",NULL,0);
  167.       /* any incoming over serial port ? */
  168.       i = GetChar(Port,0);
  169.       if(i>-1)
  170.           {/* good character */
  171.            if(DataFlag&((i<0x20)||(i>0x7e)))
  172.                {MyCrtWrite('^');
  173.                 MyCrtWrite('@'+i);
  174.                }
  175.            else MyCrtWrite(i);
  176.           }
  177.       /* any change in DCD or DSR ? */
  178.       Delta = SioModem(Port,DeltaDCD|DeltaDSR);
  179.       if(Delta)
  180.           {/* display new status */
  181.            Status = SioModem(Port,(char)(DCD|DSR));
  182.            if(!Status&DeltaDCD) MyExit(0,"Dropped DSD");
  183.            if(!Status&DeltaDSR) MyExit(0,"Dropped DSR");
  184.           }
  185.      } /* end -- key pressed */
  186. }
  187.  
  188. /*** write to screen except for bottom line ***/
  189.  
  190. void MyCrtWrite(ch)
  191. char ch;
  192. {/* write character */
  193.  SioCrtWrite(ch);
  194.  /* scroll all but bottom line */
  195.  if(GetRow()==24)
  196.     {Scroll(0,0,23,79,1,NORMAL);
  197.      Position(23,0);
  198.     }
  199. }
  200.  
  201. /*** make multiple attempts to reset port ***/
  202.  
  203. void MyStart(Port,BaudCode)
  204. int Port;
  205. int BaudCode;
  206. {int i, rc;
  207.  /* try up to 3 times to reset COM port */
  208.  for(i=0;i<3;i++)
  209.      {printf("Resetting COM%d at %s baud\n",Port+1,BaudRate[BaudCode]);
  210.       if( (rc = SioReset(Port,BaudCode))==0) return;
  211.       if(rc<0) MyExit(rc,"Error resetting port");
  212.       SioDone(Port);
  213.       /* display errors */
  214.       if(rc&OverrunError) puts("Overrun Error");
  215.       if(rc&ParityError)  puts("Parity Error");
  216.       if(rc&FramingError) puts("Framing Error");
  217.       if(rc&BreakDetect)  puts("Break Detect");
  218.      }
  219.  exit(1);
  220. }
  221.  
  222. /*** find baud rate string in table ***/
  223.  
  224. int BaudMatch(ptr)
  225. char *ptr;
  226. {int i;
  227.  /* find baud rate in table */
  228.  for(i=0;i<10;i++) if(strcmp(BaudRate[i],ptr)==0) return(i);
  229.  return(-1);
  230. }
  231.  
  232. /*** user pressed Escape */
  233.  
  234. void ProcessESC()
  235. {int i;
  236.  int rc;
  237.  int c1, c2;
  238.  char Answer[2]; /* array for 1 char answer */
  239.  int row, col;
  240.  /* user pressed <ESC> */
  241.  Answer[0] = '?';
  242.  Answer[1] = '\0';
  243.  DisplayLine("Q)uit P)rotocol S)end R)eceive: ",Answer,1);
  244.  if(strlen(Answer)) switch(toupper(Answer[0]))
  245.      {
  246.       case 'P':
  247. #if RTS_CTS_CONTROL
  248.           DisplayLine("X) xmodem Y) ymodem G) ymodem-g: ",Answer,1);
  249. #else
  250.           DisplayLine("X) xmodem Y) ymodem: ",Answer,1);
  251. #endif
  252.           if(strlen(Answer)) switch( toupper(Answer[0]) )
  253.                {
  254.                 case 'X':
  255.                     Protocol = 'X';
  256.                     ShowProtocol();
  257.                     OneKflag = FALSE;
  258.                     BatchFlag = FALSE;
  259.                     NCGchar = NAK;
  260.                     DisplayLine("Protocol = XMODEM",NULL,1);
  261.                     break;
  262.                 case 'Y':
  263.                     Protocol = 'Y';
  264.                     ShowProtocol();
  265.                     OneKflag = TRUE;
  266.                     BatchFlag = TRUE;
  267.                     NCGchar = 'C';
  268.                     DisplayLine("Protocol = YMODEM",NULL,1);
  269.                     break;
  270. #if RTS_CTS_CONTROL
  271.                 case 'G':
  272.                     Protocol = 'G';
  273.                     ShowProtocol();
  274.                     OneKflag = TRUE;
  275.                     BatchFlag = TRUE;
  276.                     NCGchar = 'G';
  277.                     DisplayLine("Protocol = YMODEM-G",NULL,1);
  278.                     break;
  279. #endif
  280.                 default:
  281.                     DisplayLine("Must answer X, Y, or G",NULL,1);
  282.